package ar.edu.unlu.sistemas.p2p.business.msg;

import java.util.StringTokenizer;

import ar.edu.unlu.sistemas.p2p.business.module.AppModule;
import ar.edu.unlu.sistemas.p2p.business.net.tcp.PeerTCPConnection;
import ar.edu.unlu.sistemas.p2p.business.util.Logger;
import ar.edu.unlu.sistemas.p2p.business.util.StringUtils;

public class MessageInterpreter {
	
	/**
	 * Interpreta el mensaje que arriba por la conexión enviada como parámetro. El mensaje es representado
	 * en formato de xml y está representado por el xml que también forma parte de los parámetros de
	 * entrada. A partir de éste ultimo se genera automáticamente el objeto mensaje correspondiente y
	 * se ejecuta el evento de aplicación que implique a partir de su código que define el protocolo de
	 * aplicación.
	 * 
	 * @param connection
	 * @param xmlContent
	 */
	public static void interpretMessage(PeerTCPConnection connection, String xmlContent) {
		Message msg = MessageFactory.buildFromXML(xmlContent);
		if (msg!=null) {
			switch (msg.getHeader().getType()) {
				case MessageFactory.CODE_CONNECT_PEER_NODE:
					AppModule.getInstance().connectionRequestedByPeer(connection, (PeerConnectionMessage)msg);
					break;
				case MessageFactory.CODE_CONNECT_PEER_NODE_ACK:
					AppModule.getInstance().peerConnected(connection, (PeerConnectionACKMessage)msg);
					break;
				case MessageFactory.CODE_DISCONNECT_PEER_NODE:
					AppModule.getInstance().disconnectionRequestedByPeer(connection.getPeer(),(PeerDisconnectionMessage)msg);
					break;
				case MessageFactory.CODE_DISCONNECT_PEER_NODE_ACK:
					AppModule.getInstance().peerDisconected(connection.getPeer(),(PeerDisconnectionACKMessage)msg);
					break;
				case MessageFactory.CODE_PING:
					AppModule.getInstance().receivePingFromPeer(connection.getPeer(),(PingMessage)msg);
					break;
				case MessageFactory.CODE_PONG:
					AppModule.getInstance().receivePongFromPeer(connection.getPeer(),(PongMessage)msg);
					break;
				case MessageFactory.CODE_QUERY:
					AppModule.getInstance().receiveQueryFromPeer(connection.getPeer(),(QueryMessage)msg);
					break;
				case MessageFactory.CODE_QUERY_RESP:
					AppModule.getInstance().receiveQueryResponse(connection.getPeer(),(QueryResponseMessage)msg);
					break;
				case MessageFactory.CODE_CONNECTION_ALIVE:
				case MessageFactory.CODE_CONNECTION_ALIVE_ACK:
				default:
					Logger.logDebug(MessageInterpreter.class.getName(),"Código de mensaje inexistente o aun no implementado. No se ejecuta ninguna acción");
			}
		} else {
			Logger.logDebug(MessageInterpreter.class.getName(),"Mensaje recibido mal formado o código de mensaje inexistente. No se ejecuta ninguna acción");
		}
	}
	
	public static String interpretMessage(String plainMessage) {
		String result;
		if(!StringUtils.esStringVacioONull(plainMessage)) {
			StringTokenizer st = new StringTokenizer(plainMessage,"|");
			String temp;
			if (st.hasMoreTokens()) {
				temp = st.nextToken();
				try {
					int code = new Integer(temp).intValue();
					boolean is300 = false;
					switch (code) {
					case 300:
						is300 = true;
					case 200:
						Integer nFiles = null;
						if (st.hasMoreTokens()) {
							temp = st.nextToken();
							nFiles = new Integer(temp).intValue();
						}
						long[] retArr = AppModule.getInstance().reIndexFiles(nFiles);
						if (is300) {
							result = AppModule.getInstance().queryTest(nFiles);
						} else {
							result = "OK|"+String.valueOf(retArr[2])+"|"+String.valueOf(retArr[0])+"|"+
								String.valueOf(retArr[1])+"|"+String.valueOf(AppModule.getInstance().findWords(null).size());
						}
						break;
					default:
						result = "ERROR: Codigo de mensaje invalido";
					}
				} catch (Exception e) {
					result = "ERROR: En la indexacion o recepcion del mensaje";
					Logger.logError(MessageInterpreter.class.getName(), result, e);
				}
			} else {
				result = "ERROR: Mensaje sin codigo";
			}
		} else {
			result = "ERROR: Mensaje vacio";
		}
		return result;
	}

}
